home *** CD-ROM | disk | FTP | other *** search
- {*********************************************************}
- {* AAHpDist *}
- {* Copyright (c) Julian M Bucknall 2000 *}
- {* All rights reserved. *}
- {*********************************************************}
- {* Algorithms Alfresco: Heap allocation distributions *}
- {*********************************************************}
-
- {Note: this unit is released as freeware. In other words, you are free
- to use this unit in your own applications, however I retain all
- copyright to the code. JMB}
-
- unit AAHpDist;
-
- {WARNING: this unit *must* appear first in your project's uses list.}
-
- interface
-
- const
- aaHeapAlign = 4;
- {-the alignment value for the heap}
- aaHeapMinAlloc = 8;
- {-the minimum allocation in bytes (exluding Size/Flags value)}
- aaHeapMaxAlloc = 512;
- {-the maximum allocation in bytes to track}
-
- type
- TaaHeapBins =
- array [aaHeapMinAlloc div aaHeapAlign ..
- succ(aaHeapMaxAlloc div aaHeapAlign)] of integer;
-
- var
- aaHeapBins : TaaHeapBins;
-
- implementation
-
- uses
- Windows, // it's OK to use Windows: it allocates no memory
- AANoMem;
-
- var
- OrigHeap : TMemoryManager;
- OurHeap : TMemoryManager;
-
- procedure UpdateBin(Size : integer);
- var
- RoundedSize : integer;
- begin
- {calculate the rounded size of the requested allocation; this is..}
- {..the actual size rounded up to the nearest aaHeapAlign bytes (4)}
- RoundedSize := (Size + aaHeapAlign - 1) and (not (integer(aaHeapAlign) - 1));
- {..if the result is less than the minimum round up to the minimum}
- if (RoundedSize < aaHeapMinAlloc) then
- RoundedSize := aaHeapMinAlloc
- {..if greater than the maximum round down to the maximum plus 4 (in other
- words, this allocation is for the 'other' bin)}
- else if (RoundedSize > aaHeapMaxAlloc) then
- RoundedSize := aaHeapMaxAlloc + aaHeapAlign;
-
- {increment the count in the relevant bin}
- InterlockedIncrement(aaHeapBins[RoundedSize div aaHeapAlign]);
- end;
-
- function OurGetMem(Size : integer) : pointer;
- begin
- {update the relevant bin}
- UpdateBin(Size);
- {go ahead and allocate the memory}
- Result := OrigHeap.GetMem(Size);
- end;
-
- function OurReallocMem(P : pointer; Size : integer) : pointer;
- begin
- {update the relevant bin; note: Size=0 is the same as a FreeMem}
- if (Size <> 0) then
- UpdateBin(Size);
- {go ahead and do the work}
- Result := OrigHeap.ReallocMem(P, Size)
- end;
-
- procedure InitializeUnit;
- begin
- {get the original manager}
- GetMemoryManager(OrigHeap);
-
- {set up our heap manager}
- OurHeap.GetMem := OurGetMem;
- OurHeap.FreeMem := OrigHeap.FreeMem;
- OurHeap.ReallocMem := OurReallocMem;
-
- {fill all bins with zeros}
- FillChar(aaHeapBins, sizeof(aaHeapBins), 0);
-
- {replace heap manager with ours}
- SetMemoryManager(OurHeap);
- end;
-
- procedure FinalizeUnit;
- var
- Log : System.Text;
- i : integer;
- LogNameZ : array [0..255] of char;
- LogName : shortstring;
- begin
- {restore the original manager}
- SetMemoryManager(OrigHeap);
-
- {get the log name}
- aaReadRegistryString(LogNameZ, 256,
- 'software\AlgorithmsAlfresco\AAHpDist',
- 'LogName',
- 'C:\HEAPDIST.LOG');
- LogName := aaStrPas(LogNameZ);
-
- {write out data to log}
- aaLogOpen(Log, LogName);
- try
- writeln(Log, 'Heap Allocation Distribution');
- writeln(Log, '----------------------------');
- writeln(Log);
- writeln(Log, 'Size':5, 'Count':10);
- for i := low(aaHeapBins) to pred(high(aaHeapBins)) do
- writeln(Log, (i * aaHeapAlign):5, aaHeapBins[i]:10);
- writeln(Log, 'Other':5, aaHeapBins[high(aaHeapBins)]:10);
- finally
- aaLogClose(Log);
- end;
- end;
-
-
- initialization
- InitializeUnit;
-
- finalization
- FinalizeUnit;
-
- end.
-